﻿using NewLife;
using NewLife.Log;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using NpmPackageDownLoad.Common;
using NpmPackageDownLoad.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NpmPackageDownLoad
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            txtLog.UseWinFormControl(false);
        }

        private void btnSetSavePath_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dialog = new FolderBrowserDialog();
            dialog.Description = "请选择文件路径";
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                txtSavePath.Text = dialog.SelectedPath;
                txtUploadFolderPath.Text = dialog.SelectedPath;
                XTrace.WriteLine($"设置保存路径成功:{ txtSavePath.Text}");
                //Log($"设置保存路径成功:{ txtSavePath.Text}");
            }
        }
        private void Log(string str)
        {
            this.txtLog.Text += str + "\r\n";
            txtLog.ScrollToCaret();
        }

        private void btnChooseJSON_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileDialog = new OpenFileDialog();
            fileDialog.Multiselect = true;
            fileDialog.Title = "请选择文件";
            fileDialog.Filter = "JSON文件(*.json)|*.json";
            if (fileDialog.ShowDialog() == DialogResult.OK)
            {
                string file = fileDialog.FileName;
                this.txtJSONPath.Text = file;
                XTrace.WriteLine($"选择文件完成，文件路径{file}");
                //MessageBox.Show("已选择文件:" + file, "选择文件提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private List<KeyValuePair<string, PackageModel>> TreeToList(Dictionary<string, PackageModel> nodes)
        {
            List<KeyValuePair<string, PackageModel>> result = new List<KeyValuePair<string, PackageModel>>();
            foreach (var item in nodes)
            {
                result.Add(new KeyValuePair<string, PackageModel>(item.Key, item.Value));
                if (item.Value.Dependencies.Count > 0)
                {
                    result.AddRange(TreeToList(item.Value.Dependencies));
                }
            }
            return result;
        }

        private string getPackageName(string resolved)
        {
            var tgzIndex = resolved.IndexOf(".tgz");
            var leftIndex = resolved.Substring(0, tgzIndex).LastIndexOf("/");
            return resolved.Substring(leftIndex + 1, tgzIndex - leftIndex + 3);
        }
        private void btnStartDown_Click(object sender, EventArgs e)
        {
            XTrace.WriteLine($"开始读取JSON文件，请稍候...");
            FileStream fs = new FileStream(this.txtJSONPath.Text, FileMode.Open);
            StreamReader streamReader = new StreamReader(fs);
            string jsonStr = streamReader.ReadToEnd();
            fs.Close();
            fs.Dispose();
            var serializerSettings = new JsonSerializerSettings
            {
                // 设置为驼峰命名
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            };
            var jsonModel = JsonConvert.DeserializeObject<JsonModel>(jsonStr, serializerSettings);
            XTrace.WriteLine($"JSON解析完成，共获取到{jsonModel.Dependencies.Count}个包");

            var models = TreeToList(jsonModel.Dependencies);

            Task<int> task = new Task<int>(() =>
            {

                int index = 0;

                foreach (var item in models)
                {
                    if (item.Value.Resolved.IsNullOrEmpty()) {
                        index++;
                        continue;
                    }
                    string packageName = getPackageName(item.Value.Resolved);
                    //string packageName = $"{item.Key}-{item.Value.Version}.tgz";
                    //if (packageName.Split("/").Length > 1)
                    //{
                    //    packageName =  packageName.Split("/")[packageName.Split("/").Length - 1];
                    //}
                    try
                    {

                        System.Net.WebClient client = new System.Net.WebClient();
                        byte[] data = client.DownloadData(item.Value.Resolved);
                        (txtSavePath.Text + "\\" + item.Key.Replace("/", "\\") + "\\").EnsureDirectory();
                        FileStream fs1 = new FileStream(txtSavePath.Text + "\\" + item.Key.Replace("/", "\\") + "\\" + packageName, FileMode.OpenOrCreate);
                        //将byte数组写入文件中
                        fs1.Write(data, 0, data.Length);
                        fs1.Close();
                        fs1.Dispose();
                        XTrace.WriteLine($"[{++index}/{models.Count}]:{packageName}完成");
                    }
                    catch (Exception ex)
                    {
                        XTrace.WriteLine($"[{++index}/{models.Count}]:{packageName}失败。{ex.Message}");
                    }

                }
                return DateTime.Now.Year;
            });
            task.Start();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            tabControl1.TabPages[0].Text = "包下载（外网环境）";
            tabControl1.TabPages[1].Text = "包上传（内网环境）";
            ConfigModel config = Util.GetConfig();
            if (config != null)
            {
                txtExt.Text = config.FileExt;
                txtUploadFolderPath.Text = config.PackageFolderPath;
                txtUploadFileKey.Text = config.UploadeFileKey;
                txtUploadUrl.Text = config.UploadUrl;
            }
        }



        private void btnChangeUploadFolderPath_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dialog = new FolderBrowserDialog();
            dialog.Description = "请选择文件夹";
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                txtUploadFolderPath.Text = dialog.SelectedPath;
                XTrace.WriteLine($"更换文件夹成功:{ txtSavePath.Text}");
                //Log($"设置保存路径成功:{ txtSavePath.Text}");
            }
        }
        public void EnableUploadButton()
        {
            this.btnUpload.Enabled = true;
        }
        public void DisableUploadButton()
        {
            this.btnUpload.Enabled = false;
        }

        private void btnUpload_Click(object sender, EventArgs e)
        {
            Util.SetConfig(new ConfigModel()
            {
                FileExt = txtExt.Text,
                PackageFolderPath = txtUploadFolderPath.Text,
                UploadeFileKey = txtUploadFileKey.Text,
                UploadUrl = txtUploadUrl.Text
            });
            //MessageBox.Show("成功");
            XTrace.WriteLine($"开始读取文件夹:{  txtUploadFolderPath.Text }");
            var packages = Directory.GetFiles(txtUploadFolderPath.Text, txtExt.Text, SearchOption.AllDirectories);
            XTrace.WriteLine($"获取到:{  packages.Length }个包。");
            XTrace.WriteLine($"开始上传：");
            Task<int> task = new Task<int>(() =>
            {
                int index = 0;
                foreach (var item in packages)
                {
                    try
                    {
                        Util.HttpUploadFile(this.txtUploadUrl.Text, item, this.txtUploadFileKey.Text);
                        XTrace.WriteLine($"[{++index}/{packages.Length}]:{item}完成");
                    }
                    catch (Exception ex)
                    {
                        XTrace.WriteLine($"[{++index}/{packages.Length}]:{item}失败。{ex.Message}");
                    }
                }
                this.Invoke(EnableUploadButton);
                return DateTime.Now.Year;
            });
            task.Start();
            DisableUploadButton();
        }
    }
}
